#pragma once 

#include <iostream>
#include <unordered_map>
#include <cassert>
#include <vector>
#include <mysql/mysql.h>

#include "../common/util.hpp"
#include "../common/log.hpp"

namespace rs_model
{
    using namespace std;
    using namespace rs_log;
    using namespace rs_util;

    

    class Question
    {
    public:
        std::string number;
        std::string title;
        std::string grade;
        int cpu_limit;
        int mem_limit;

        string desc;
        string header;
        string tail;
    };

    const string host = "127.0.0.1";
    const string user = "my_oj";
    const string pass = "123456";
    const string db = "oj_server";
    const int port = 3306;
    const string all_questions="oj_questions ";

    class Model
    {
    private:
        std::unordered_map<std::string,Question>    questions;
    public:
        Model()
        {   
            
        }

        bool QueryMysql(std::string &sql,vector<Question> *out)
        {
            MYSQL* ms = mysql_init(nullptr);

            if(nullptr == mysql_real_connect(ms,host.c_str(),user.c_str(),pass.c_str(),db.c_str(),port,nullptr,0))
            {
                LOG(FATAL) << "连接数据库失败" <<endl;
                return false;
            }

            mysql_set_character_set(ms,"utf8");

            LOG(INFO) << "连接数据库成功" <<endl;

            if(0!=mysql_query(ms,sql.c_str()))
            {
                LOG(ERROR)<<"数据库执行指令失败"<<endl;
                return false;
            }

            Question q;

            MYSQL_RES *res = mysql_store_result(ms);

            int row = mysql_num_rows(res);
            

            for(int i =0 ;i < row;i++)
            {
                MYSQL_ROW row = mysql_fetch_row(res);

                q.number = row[0];
               
                q.title = row[1];
               
                q.grade = row[2];
                
                q.desc = row[3];
                q.header = row[4];
                q.tail = row[5];
                q.cpu_limit = atoi(row[6]);
                q.mem_limit = atoi(row[7]);
                out->push_back(q);

            }
            
            //free(res);
            mysql_close(ms);
            return true;
        }

        bool GetAllQuestion(vector<Question> *out)
        {
            
            std::string sql = "select * from ";
            sql += all_questions;
            return QueryMysql(sql,out);
        }
        
        bool GetOneQuestion(const string& number,Question* out)
        {
            bool res = false;
            std::string sql = "select * from ";
            sql += all_questions;
            sql += "where id =";
            sql += number;
            std::vector<Question> qnum;
            if(QueryMysql(sql,&qnum))
            {
                if(qnum.size() == 1)
                {
                    *out = qnum[0];
                    res = true;
                }
            }

            return res;
        }
        ~Model()
        {}
    };
}

